package com.atguigu.tingshu.album.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.config.MinioConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;
    @Autowired
    private MinioConstantProperties minioConstantProperties;
    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;
    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Override
    public String uploadFile(MultipartFile file) {
        //先创建minio客户端
        MinioClient minioClient = MinioClient.builder()
                .endpoint(minioConstantProperties.getEndpointUrl())
                .credentials(minioConstantProperties.getAccessKey(), minioConstantProperties.getSecreKey())
                .build();

        //生成一个UUID防止重复上传后失效
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        //获取文件后缀并拼接uuid
        String filename =  uuid + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        //开始实现文件上传功能
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(minioConstantProperties.getBucketName())
                    .contentType(file.getContentType())
                    .object(filename)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .build();
            minioClient.putObject(putObjectArgs);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return minioConstantProperties.getEndpointUrl() + "/" + minioConstantProperties.getBucketName() + "/"  + filename;
    }

    @Override
    public void saveAlbumInfo(AlbumInfo albumInfo) {

          //不仅涉及到album_infoz这张表，还需要保存album_attribute_value表(自己从前端传入的属性与属性值,
          //这里的属性有很多是重复的，比如是否付费，会重复出现，但是就是为了跟最大的分类设计的，比如有声书，什么小说的)
          //其次对于每一个专辑，都有一级分类，也就都有属性,然后通过属性找到属性值，这么设计是架构师根据业务调整的结果所以没什么区别
          //能否拿到高薪并且工作不辛苦，两个方面，一是思路的架构，即顶层的设计和理解 二是操作 即肌肉记忆和经验。 有思路后很好，实现过程和测试过程就是经验的体现，所以要培养独立思考，独立操作，借助ai提高生产效率，见多识广，不断犯错，多问，多犯错，从而提升开发效率。
          //目前开始实现savealubminfo接口
         /*
         * albuminfo 缺少：
         * id 自动增加，还会回显
         * userId 从本地线程中拿到userId，是网关传给mvc的拦截器
         * 由拦截器放入本地线程当中
         * qualityScore 这个评分可以给个平均分，造一下假数据线
         * status 审核通过/审核不通过
         * */
        albumInfo.setQualityScore("3");
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        albumInfo.setUserId(AuthContextHolder.getUserId() == null ? 1L : AuthContextHolder.getUserId() );
        if(!albumInfo.getPayType().equals(SystemConstant.ALBUM_PAY_TYPE_FREE)){
            //设置免费试听集数
            albumInfo.setTracksForFree(5);

        }
        albumInfoMapper.insert(albumInfo);


         /*
         * 还需要往album_attribute_value表中插入数据
         * */
        albumInfo.getAlbumAttributeValueVoList().stream().forEach(
                albumAttributeValueVo -> {
                    albumAttributeValueVo.setAlbumId(albumInfo.getId());
                    albumAttributeValueMapper.insert(albumAttributeValueVo);
                }
        );

        /*
        * 还需要往alubm_statistics表中插入数据
        * */

        for (int i = 1; i <= 4; i++) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumInfo.getId());
        albumStat.setStatType("040" + i);
        albumStat.setStatNum(99);
        albumStatMapper.insert(albumStat);
        }




    }

    @Override
    public IPage<Map<String, Object>> findUserAlbumPage(Page<Map<String, Object>> page, AlbumInfoQuery albumInfoQuery) {


        Page<Map<String, Object>> mapPage = albumInfoMapper.selectMapsPage(page, new LambdaQueryWrapper<AlbumInfo>()
                .eq(AlbumInfo::getUserId, 1L)
                .eq(StringUtils.hasText(albumInfoQuery.getStatus()),AlbumInfo::getStatus,albumInfoQuery.getStatus())
                .orderBy(true,false, AlbumInfo::getId)
                .like(StringUtils.hasText(albumInfoQuery.getAlbumTitle()),AlbumInfo::getAlbumTitle,albumInfoQuery.getAlbumTitle())
        );

        mapPage.getRecords().stream().forEach(
                map -> {
                    //id改名
                    map.put("albumId", map.get("id"));
                    map.remove("id");
                   //删除不需要返回的字段
                    map.remove("user_id");
                    map.remove("category3_id");
                    map.remove("album_intro");
                    map.remove("estimated_track_count");
                    map.remove("album_rich_intro");
                    map.remove("quality_score");
                    map.remove("pay_type");
                    map.remove("price_type");
                    map.remove("price");
                    map.remove("discount");
                    map.remove("vip_discount");
                    map.remove("tracks_for_free");
                    map.remove("seconds_for_free");
                    map.remove("buy_notes");
                    map.remove("selling_point");
                    map.remove("is_open");
                    map.remove("create_time");
                    map.remove("update_time");
                    map.remove("is_deleted");
                //将需要的字段从下划线改成JSON需要的驼峰式
                    map.put("albumTitle", map.get("album_title"));
                    map.remove("album_title");

                    map.put("coverUrl", map.get("cover_url"));
                    map.remove("cover_url");

                    map.put("includeTrackCount", map.get("include_track_count"));
                    map.remove("include_track_count");

                    map.put("isFinished", map.get("is_finished"));
                    map.remove("is_finished");

                    //查询album_statistics表，封装统计值数
                   AlbumStat  albumStatForPlayNum =  albumStatMapper.selectOne(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, map.get("albumId")).eq(AlbumStat::getStatType, SystemConstant.ALBUM_STAT_PLAY));
                   map.put("playStatNum", albumStatForPlayNum.getStatNum());

                   AlbumStat  albumStatForSubscribeNum =  albumStatMapper.selectOne(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, map.get("albumId")).eq(AlbumStat::getStatType, SystemConstant.ALBUM_STAT_SUBSCRIBE));
                   map.put("commentStatNum", albumStatForSubscribeNum.getStatNum());

                   AlbumStat  albumStatForBuyStatNum =  albumStatMapper.selectOne(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, map.get("albumId")).eq(AlbumStat::getStatType, SystemConstant.ALBUM_STAT_BROWSE));
                   map.put("buyStatNum", albumStatForBuyStatNum.getStatNum());

                   AlbumStat  albumStatFromCommentStatNum =  albumStatMapper.selectOne(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, map.get("albumId")).eq(AlbumStat::getStatType, SystemConstant.ALBUM_STAT_COMMENT));
                   map.put("albumCommentStatNum", albumStatFromCommentStatNum.getStatNum());

                }
        );

        return mapPage;
    }


}
